package com.ys.service.finance.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.dto.AddDto;
import com.ys.entity.finance.TcwWanliDrawing;
import com.ys.entity.finance.TcwWanliDrawingItem;
import com.ys.entity.finance.TcwWanliFinance;
import com.ys.entity.flow.YspModel;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsCol;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.mapper.finance.FinanceMapper;
import com.ys.mapper.finance.TcwWanliDrawingItemMapper;
import com.ys.mapper.finance.TcwWanliDrawingMapper;
import com.ys.service.finance.TcwAccountCountForWanliService;
import com.ys.service.finance.TcwWanliDrawingService;
import com.ys.service.finance.TcwWanliPayoutService;
import com.ys.service.flow.YspTaskService;
import com.ys.util.CheckUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

/**
 * 万里汇提款单
 */
@Service("tcwWanliDrawingService")
public class TcwWanliDrawingServiceImpl implements TcwWanliDrawingService {
	private static final Logger logger = LoggerFactory.getLogger(TcwWanliDrawingServiceImpl.class);

	@Autowired
	private TcwWanliDrawingMapper tcwWanliDrawingMapper;

	@Autowired
	private TcwWanliDrawingItemMapper tcwWanliDrawingItemMapper;

	@Autowired
	private YspTaskService yspTaskService;

	@Autowired
	private CheckUtil checkUtil;

	@Autowired
	private FinanceMapper financeMapper;

	@Autowired
	private TcwWanliPayoutService tcwWanliPayoutService;

	@Autowired
	private TcwAccountCountForWanliService tcwAccountCountForWanliService;

	/**
	 * 新增
	 */
	@Override
	public R add(Map<String, Object> params, Long menuId) throws Exception{
		logger.info("新增传参:"+params);
		//参数验证
		String errorBack = checkParams(params, menuId);
		if(errorBack!=null && !"".equals(errorBack)){
			return R.error(errorBack);
		}
		TcwWanliDrawing tcwWanliDrawing = JSON.parseObject(JSON.toJSONString(params), TcwWanliDrawing.class);
		tcwWanliDrawing.setStatus(1);//状态
		tcwWanliDrawing.setEffectStock(0);//审批状态

		//获取制单人信息
		TsUserChange tsUserChange = new TsUserChange().setUserId(ShiroUtils.getUserId()).setOrderby("A.CreateTime DESC").queryFirst();
		if(tsUserChange!=null){
			tcwWanliDrawing.setCreateChangeId(tsUserChange.getId());//制单人变更信息
		}else {
			return R.error("未查询到制单人信息！");
		}

		//保存列表信息
		R saveItemRes = saveItem(params,tcwWanliDrawing);
		if(saveItemRes.getCode()==1){
			return saveItemRes;
		}

		//新增
		tcwWanliDrawingMapper.insert(tcwWanliDrawing);

		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, tcwWanliDrawing.getBid(), createUserId);
		}
		//return R.ok(EditDto.closeAndReload());
		return R.ok(AddDto.gotoEdit("/web/finance/tcwWanliDrawing/toEdit?bid=" + tcwWanliDrawing.getBid()));
	}


	/**
	 * 修改
	 */
	@Override
	public R update(Map<String, Object> params, Long menuId) throws Exception{
		logger.info("修改传参:"+params);
		//参数验证
		String errorBack = checkParams(params, menuId);
		if(errorBack!=null && !"".equals(errorBack)){
			return R.error(errorBack);
		}
		TcwWanliDrawing tcwWanliDrawing = JSON.parseObject(JSON.toJSONString(params), TcwWanliDrawing.class);
		// 验证状态
		YsProcInst ysProcInst = new YsProcInst().setBid(tcwWanliDrawing.getBid()).queryFirst();
		if (ysProcInst == null) {
			return R.error("审批数据不存在，无法编辑");
		} else if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.INIT.value) {
			return R.error("已流转，无法编辑");
		}

		//保存列表信息
		R saveItemRes = saveItem(params,tcwWanliDrawing);
		if(saveItemRes.getCode()==1){
			return saveItemRes;
		}
		tcwWanliDrawingMapper.update(tcwWanliDrawing);
		return R.ok();
	}


	//保存列表信息
	public R saveItem(Map<String, Object> params,TcwWanliDrawing tcwWanliDrawing){
		//保存列表信息
		List<Map<String, Object>> paramsNewByItem = new ArrayList<>();
		if(params.get("subData")!=null){
			//验证详情信息
			JSONArray subDataArray = JSON.parseArray(params.get("subData").toString());
			String errorBackByItem = null;//错误信息
			if(subDataArray!=null && subDataArray.size()>0){
				for (int i = 0; i < subDataArray.size(); i++) {
					JSONObject jsonObject = subDataArray.getJSONObject(i);
					Map<String, Object> paramsNewByRecord = new HashMap<>();
					for (String key : jsonObject.keySet()) {
						paramsNewByRecord.put(key, jsonObject.get(key));
					}
					paramsNewByItem.add(paramsNewByRecord);
				}
				for (int i = 0; i < paramsNewByItem.size(); i++) {
					Map<String, Object> paramsNewByRecord = paramsNewByItem.get(i);
					if(!checkUtil.isNotNullByObject(paramsNewByRecord.get("companyBankInfoId"))){
						errorBackByItem = "第"+(i+1)+"行的收款账户调取信息为空！";
					}
					if(!checkUtil.isNotNullByObject(paramsNewByRecord.get("outCurrencyCode"))){
						errorBackByItem = "第"+(i+1)+"行的汇出币种信息为空！";
					}
					if(tcwWanliDrawing.getDrawingType()==0){//提款
						if(!checkUtil.isNotNullByObject(paramsNewByRecord.get("outSum"))){
							errorBackByItem = "第"+(i+1)+"行的汇出金额为空！";
						}
					}else{//到款
						if(!checkUtil.isNotNullByObject(paramsNewByRecord.get("inSum"))){
							errorBackByItem = "第"+(i+1)+"行的汇入金额为空！";
						}
					}
					//paramsNewByItem.add(paramsNewByRecord);
				}
				if(errorBackByItem!=null && !"".equals(errorBackByItem)){
					return R.error(errorBackByItem);
				}
			}else {
				return R.error("列表信息为空！");
			}
		}else {
			return R.error("列表信息为空！");
		}

		//删除列表信息
		financeMapper.deleteWorldFirstDrawingItemByPbid(tcwWanliDrawing.getBid());
		for (int i = 0; i < paramsNewByItem.size(); i++) {
			Map<String, Object> item = paramsNewByItem.get(i);
			TcwWanliDrawingItem tcwWanliDrawingItem = JSON.parseObject(JSON.toJSONString(item), TcwWanliDrawingItem.class);
			tcwWanliDrawingItem.setStatus(1);
			tcwWanliDrawingItem.setPbid(tcwWanliDrawing.getBid());
			tcwWanliDrawingItem.setInCurrencyCode("CNY");//汇入币种，默认CNY
			//新增
			tcwWanliDrawingItemMapper.insert(tcwWanliDrawingItem);
			/*
			if(tcwWanliDrawingItem.getId()!=null){
				//修改
				tcwWanliDrawingItemMapper.update(tcwWanliDrawingItem);
			}else {
				//新增
				tcwWanliDrawingItemMapper.insert(tcwWanliDrawingItem);
			}

			 */
		}
		return R.ok();
	}


	//删除
	@Override
	@Transactional
	public R del(Long id) throws Exception{
		if (id == null) {
			return R.error("ID不能为空");
		}
		TcwWanliDrawing entity = new TcwWanliDrawing().setId(id).queryFirst();
		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("已生效数据无法删除");
		}
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
		if (!tsUserChange.getUserId().equals(loginUserId) && !"admin".equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}
		//删除
		tcwWanliDrawingMapper.deleteTrue(id);
		//删除列表信息
		financeMapper.deleteWorldFirstDrawingItemByPbid(entity.getBid());
		//删除流程
		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}

	//删除列表
	@Override
	@Transactional
	public R toDelByItem(Long id) throws Exception{
		tcwWanliDrawingItemMapper.deleteTrue(id);
		return R.ok();
	}

	/**
	 * 流转通过
	 */
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R flowPass(Long id, String loginUserId) throws Exception {

		TcwWanliDrawing entity = new TcwWanliDrawing().setId(id).queryFirst();
		Flow f = yspTaskService.flowPass(entity.getBid(), loginUserId);
		if (f.getCode() == Flow.Code.FAILED.value) {
			return R.error(f.getMsg());
		} else {
			if (f.getState() == Flow.State.FINISH.value) {
				return flowFinish(entity.getBid());
			}
			return R.ok();
		}
	}

	/**
	 * 流转结束
	 */
	@Override
	public R flowFinish(String bid) throws Exception {

		TcwWanliDrawing entity = new TcwWanliDrawing().setBid(bid).queryFirst();
//		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
//		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
//			return R.error();
//		}
//		Date theDate = new Date();
//		entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
//		entity.setUpdateTime(theDate);
//
//		//查询子件信息
		List<TcwWanliDrawingItem> tcwWanliDrawingItemList = new TcwWanliDrawingItem().setPbid(bid).queryList();
//
//		String resultMessage = null;
//		for (int i=0;i<tcwWanliDrawingItemList.size();i++){
//			TcwWanliDrawingItem tcwWanliDrawingItem = tcwWanliDrawingItemList.get(i);
//			//判断万里汇账号资金是否充足
//			//获取万里汇账号资金信息
//			TcwWanliFinance tcwWanliFinance = new TcwWanliFinance()
//					.setDepositPlatformCode(entity.getDepositPlatformCode())
//					.setExchangeRateCode(tcwWanliDrawingItem.getOutCurrencyCode()).queryFirst();
//			if(tcwWanliFinance!=null) {
//				BigDecimal accountCount = tcwWanliDrawingItem.getOutSum().compareTo(BigDecimal.ZERO)>0?tcwWanliDrawingItem.getOutSum().abs():tcwWanliDrawingItem.getOutSum();
//				//判断资金是否充足
//				BigDecimal systemSumCount = tcwWanliFinance.getSystemSum().add(accountCount);
//				if (systemSumCount.compareTo(BigDecimal.ZERO) < 0) {
//					resultMessage = "第"+(i+1)+"行对应的万里汇账号资金不足";
//				}
//			}else{
//				resultMessage = "未查询到万里汇账号资金信息";
//			}
//		}
//		if(resultMessage!=null){
//			throw new IllegalArgumentException(resultMessage);
//			//return R.error(resultMessage);
//		}
//
//		//修改信息
//		tcwWanliDrawingMapper.update(entity);

		for (TcwWanliDrawingItem tcwWanliDrawingItem : tcwWanliDrawingItemList){
			tcwWanliPayoutService.tkAdd(tcwWanliDrawingItem.getId());
		}
		return R.ok();
	}

	/**
	 * 参数验证
	 */
	public String checkParams(Map<String, Object> params, Long menuId) throws Exception {
		//获取pc字段数据
		List<YsCol> listField = new YsCol()
				.where("A.MenuId = "+menuId)
				.setOrderby("A.SortNo ASC")
				.queryList();
		//验证必填字段的非空；其他字段的长度限制、类型
		String backMsg = checkUtil.checkTableColLengthAndDataType("TCW_WorldFirstDrawing",listField,params,ysColItem->ysColItem.getFormEditRequired()!=null && ysColItem.getFormEditRequired() == 1);
		return backMsg;
	}



	@Override
	public void paySuccess(Long id) throws Exception {
		TcwWanliDrawingItem tcwWanliDrawingItem = new TcwWanliDrawingItem().setId(id).queryFirst();
		tcwWanliDrawingItem.setApiBackStatus(1);

		TcwWanliDrawing tcwWanliDrawing = new TcwWanliDrawing().setBid(tcwWanliDrawingItem.getPbid()).queryFirst();

		//新增流水
		R add = tcwAccountCountForWanliService.add(false, tcwWanliDrawing.getDepositPlatformCode(),
				tcwWanliDrawingItem.getOutCurrencyCode(),0,tcwWanliDrawingItem.getPbid(),
				tcwWanliDrawingItem.getOutSum().compareTo(BigDecimal.ZERO)>0?tcwWanliDrawingItem.getOutSum().abs():tcwWanliDrawingItem.getOutSum(),
				"单号："+tcwWanliDrawingItem.getPbid()+"；本单备注："+tcwWanliDrawing.getRemark()+"（“本金”汇率："+tcwWanliDrawingItem.getExchangeRate()+"；手续费："+tcwWanliDrawingItem.getProceduresSum()+"）");

		tcwWanliDrawingItemMapper.update(tcwWanliDrawingItem);
	}


	//获取列表数据
	@Override
	@Transactional
	public Map<String,Object> getExtraParam( String bid) throws Exception{
		Map<String,Object> entity = new TcwWanliDrawing()

				.addLeftJoin("YS_ProcInst P ON P.Bid = A.Bid ")
				.addField("FORMAT(P.UpdateTime, 'yyyy-MM-dd HH:mm:ss') AS auditingTime")//审核时间

				.addLeftJoin("TCW_DepositPlatform D ON D.Code = A.DepositPlatformCode ")//万里汇账号资金
				.addField("D.PlatformName AS platformName")//收款平台名称
				.addField("D.Code AS depositPlatformCode")//账号编码
				.addField("D.Name AS name")//账号名称
				.addField("D.Mid AS depositPlatformMid")

				.addLeftJoin("TB_CompanyInfo O ON O.Vid = D.CompanyVid ")//公司信息表
				.addField("O.Vname AS vname")//公司名称

				.setBid(bid)
				.queryFirstMap();

		return entity;
	}
	//获取子列表数据
	@Override
	@Transactional
	public List<Map<String, Object>> getItemList( String bid) throws Exception{
		List<Map<String, Object>> itemList = new TcwWanliDrawingItem()
				.addLeftJoin("TB_CompanyBankInfo CB ON CB.Id = A.CompanyBankInfoId ")//公司银行账户管理表
				.addField("CB.Vid AS vid")//收款账户编码
				.addField("CB.Vyhzhmc AS vyhzhmc")//收款账户名称
				.addField("CB.Vyhzh AS vyhzh")//收款账号
				.addField("CB.Vkhh AS vkhh")//收款开户行
				.setPbid(bid)
				.queryMap();
		return itemList;
	}


}
